#ifndef __PINFLOW_TASK_H__
#define __PINFLOW_TASK_H__

#include "thread_safe_list.h"
#include "config.h"

#include <string>
#include <assert.h>

namespace pinflow {

enum WorkloadType {
    WorkloadCPU,
    WorkloadOPENCL,
    WorkloadCUDA,
    WorkeloadNPU,
    WorkeloadCVIP,
    WorkerDSP
}; // enum WorkloadType

struct InOutBase {
    using sptr = std::shared_ptr<InOutBase>;
};

class TaskBase
{
public:
    using sptr = std::shared_ptr<TaskBase>;
    
    ~TaskBase() {}

    virtual bool Process(const ThreadSafeList<InOutBase::sptr>::sptr& inputs,
        ThreadSafeList<InOutBase::sptr>::sptr& outputs) {
        (void)inputs;
        (void)outputs;
        assert(false);
        return true;
    }

    bool Mask() const { return mask_;}

    const std::string& Name() const {return name_;}

    const std::string& InputName() const
    {
        return input_queue_;
    }

    const std::string& OutputName() const
    {
        return output_queue_;
    }

protected:
    TaskBase(const std::string& name): name_(name), mask_(true) {}

private:
    std::string name_;
    WorkloadType type_;
    std::string input_queue_;
    std::string output_queue_;
    bool mask_; // control exe or not
}; // class TaskBase

typedef TaskBase::sptr (*TaskCreatorFunc)();

class TaskRegister
{
public:
    TaskRegister(const std::string& name, TaskCreatorFunc func)
    {
        if (factory_.count(name) > 0) {
            return;
        }
        factory_[name] = func;
    }

private:
    std::map<std::string, TaskCreatorFunc> factory_ = {};
}; // class TaskRegister

#define REGISTE_TASK(TASK) \
    TaskBase::sptr TaskCreatorFunc_##TASK() { \
        return std::make_shared<TASK>(); \
    } \
    TaskRegister g_##TASK##_instance(#TASK, TaskCreatorFunc_##TASK);
} // namespace pinflow

#endif // __PINFLOW_LOAD_H__